package com.example.webmodule.strategy;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.fastjson2.JSON;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.example.webmodule.entity.ServiceInfo;
import com.example.webmodule.listener.NacosListener;
import com.example.webmodule.properties.NacosYamlProperties;
import com.example.webmodule.util.ConvertVoUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

@Slf4j
public class NacosRegistryStrategy extends AbstractWebRegistryStrategy {

    private NacosDiscoveryProperties nacosDiscoveryProperties;

    private NamingService namingService;

    public NacosRegistryStrategy(NacosDiscoveryProperties nacosDiscoveryProperties, OkHttpClient okHttpClient) {
        super(okHttpClient);
        this.nacosDiscoveryProperties = nacosDiscoveryProperties;
        Properties properties = new Properties();
        properties.setProperty("serverAddr", nacosDiscoveryProperties.getServerAddr());
        properties.setProperty("namespace", nacosDiscoveryProperties.getNamespace());
        properties.setProperty("username", nacosDiscoveryProperties.getUsername());
        properties.setProperty("password", nacosDiscoveryProperties.getPassword());
        try {
            this.namingService = NacosFactory.createNamingService(properties);
        } catch (NacosException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 订阅已有服务
     * @throws NacosException
     */
    @Override
    public void init() throws NacosException {
        log.info("subscribe init start");
        List<String> services = getServices();
        for (String serviceId: services) {
            log.info("subscribe serviceId={}", serviceId);
            // 订阅服务变化
            namingService.subscribe(
                    serviceId, nacosDiscoveryProperties.getGroup(),
                    new NacosListener(serviceId, nacosDiscoveryProperties.getGroup()));
        }
    }

    @Override
    public void subscribe(String serviceName) {
        // 订阅服务变化
        try {
            namingService.subscribe(
                    serviceName, nacosDiscoveryProperties.getGroup(),
                    new NacosListener(serviceName, nacosDiscoveryProperties.getGroup()));
        }
        catch (NacosException e) {
            log.info("subscribe error", e);
        }
    }

    @Override
    public List<String> getServices() {
        List<String> serverList = Lists.newArrayList();
        try {
            serverList = namingService.getServicesOfServer(
                    1, Integer.MAX_VALUE, nacosDiscoveryProperties.getGroup()).getData();
        } catch (NacosException e) {
            log.error("getServices error", e);
        }
        return serverList;
    }

    @Override
    public List<ServiceInfo> getServiceInstances(String serviceName) throws Exception {
        List<Instance> instanceList = namingService.getAllInstances(
                serviceName, nacosDiscoveryProperties.getGroup());

        List<ServiceInfo> result = new ArrayList<>();
        for (Instance instance: instanceList) {
            /**
             * {
             * 		"metadata": "{\"management.endpoints.web.base-path\":\"/ey/actuator\",\"preserved.register.source\":\"SPRING_CLOUD\"}",
             * 		"instanceId": "192.168.56.1#8093##default@@multi-platform-module",
             * 		"port": "8093",
             * 		"ip": "192.168.56.1"
             *        }
             */
            result.add(ConvertVoUtil.convertInstaceToServiceInfo(instance));
        }
        return result;
    }
}
